﻿// Decompiled with JetBrains decompiler
// Type: MCM.Common.RefWrapper
// Assembly: MCMv5, Version=5.10.2.0, Culture=neutral, PublicKeyToken=null
// MVID: 7AB326B9-B2B4-41C2-9177-68E944071101
// Assembly location: D:\steam\steamapps\workshop\content\261550\2859238197\bin\Win64_Shipping_Client\MCMv5.dll

using HarmonyLib.BUTR.Extensions;
using System;
using System.ComponentModel;

#nullable enable
namespace MCM.Common
{
  public class RefWrapper : IRef, INotifyPropertyChanged, IWrapper
  {
    private readonly RefWrapper.GetTypeDelegate? _getTypeDelegate;
    private readonly RefWrapper.GetValueDelegate? _getValueDelegate;
    private readonly RefWrapper.SetValueDelegate? _setValueDelegate;

    public object Object { get; }

    public event PropertyChangedEventHandler? PropertyChanged
    {
      add
      {
        if (!(this.Object is INotifyPropertyChanged notifyPropertyChanged))
          return;
        notifyPropertyChanged.PropertyChanged += value;
      }
      remove
      {
        if (!(this.Object is INotifyPropertyChanged notifyPropertyChanged))
          return;
        notifyPropertyChanged.PropertyChanged -= value;
      }
    }

    public Type Type => this._getTypeDelegate();

    public object? Value
    {
      get => this._getValueDelegate();
      set
      {
        if (this._setValueDelegate == null || value == null)
          return;
        this._setValueDelegate(value);
      }
    }

    public RefWrapper(object @object)
    {
      this.Object = @object;
      Type type = @object.GetType();
      this._getTypeDelegate = AccessTools2.GetPropertyGetterDelegate<RefWrapper.GetTypeDelegate>(@object, type, nameof (Type));
      this._getValueDelegate = AccessTools2.GetPropertyGetterDelegate<RefWrapper.GetValueDelegate>(@object, type, nameof (Value));
      this._setValueDelegate = AccessTools2.GetPropertySetterDelegate<RefWrapper.SetValueDelegate>(@object, type, nameof (Value));
    }

    private delegate Type GetTypeDelegate();

    private delegate object GetValueDelegate();

    private delegate void SetValueDelegate(object value);
  }
}
